package com.bitbakery.plugin.cl.lang;

import com.bitbakery.plugin.cl.lang.psi.CLDefun;
import com.bitbakery.plugin.cl.lang.psi.CLElement;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.util.Icons;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

public class CLStructureViewElement implements StructureViewTreeElement<CLElement> {
    private CLElement myParent;
    private CLElement myElement;

    public CLStructureViewElement(final CLElement element) {
        this(null, element);
    }

    public CLStructureViewElement(final CLElement parent, final CLElement element) {
        myParent = parent;
        myElement = element;
    }

    public CLElement getValue() {
        return myElement;
    }

    public void navigate(boolean requestFocus) {
        myElement.navigate(requestFocus);
    }

    public boolean canNavigate() {
        return myElement.canNavigate();
    }

    public boolean canNavigateToSource() {
        return myElement.canNavigateToSource();
    }

    public StructureViewTreeElement[] getChildren() {
        final List<CLElement> childrenElements = new ArrayList<CLElement>();

        myElement.accept(new CLElementVisitor() {
            public void visitElement(PsiElement element) {
                if (element instanceof CLDefun) {
                    childrenElements.add((CLElement) element);
                }
            }
        });

        return psiToStructureView(childrenElements);
    }

    private StructureViewTreeElement[] psiToStructureView(final List<CLElement> childrenElements) {
        StructureViewTreeElement[] children = new StructureViewTreeElement[childrenElements.size()];
        for (int i = 0; i < children.length; i++) {
            children[i] = new CLStructureViewElement(myElement, childrenElements.get(i));
        }
        return children;
    }

    public ItemPresentation getPresentation() {
        return new ItemPresentation() {
            public String getPresentableText() {
                if (!(myElement instanceof PsiNamedElement)) {
                    return myElement.getText();
                }

                String name = myElement.getName();

                if (myElement instanceof CLDefun) {
                    if (name == null) {
                        name = "<anonymous>";
                    }
                }
                return name;
            }

            public TextAttributesKey getTextAttributesKey() {
                return null;
            }

            public String getLocationString() {
                return null;
            }

            public Icon getIcon(boolean open) {
                return Icons.METHOD_ICON;
            }
        };
    }
}
